package com.yuxl.admin.manager.auth.server.controller;

import com.yuxl.admin.common.core.utils.R;
import com.yuxl.admin.manager.auth.core.entity.AuthOperate;
import com.yuxl.admin.manager.auth.core.entity.AuthOperate;
import com.yuxl.admin.manager.auth.core.entity.AuthRole;
import com.yuxl.admin.manager.auth.core.repository.AuthOperateRepository;
import com.yuxl.admin.manager.auth.core.repository.AuthOperateRepository;
import com.yuxl.admin.manager.auth.core.repository.AuthRolePowerRepository;
import com.yuxl.admin.manager.auth.core.repository.AuthRoleRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author : yuxl
 * @create 2024/10/29 10:16
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/manager/operate")
@Tag(name = "操作管理", description = "操作的 CRUD 操作")
public class AuthOperateController {

    private final AuthOperateRepository authOperateRepository;
    private final AuthRolePowerRepository authRolePowerRepository;
    private final AuthRoleRepository authRoleRepository;
    /**
     * 创建新操作
     * @param entity 要创建的操作对象
     * @return 创建成功的操作对象
     */
    @PostMapping
    @Operation(summary = "创建新操作", description = "创建一个新的操作")
    public Mono<R<AuthOperate>> create(@RequestBody AuthOperate entity) {
        // 保存新操作到数据库
        entity.setCreateTime(LocalDateTime.now());
        return R.ok(authOperateRepository.save(entity));
    }

    /**
     * 根据ID获取操作
     * @param id 操作ID
     * @return 操作对象
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取操作", description = "根据ID获取操作信息")
    public Mono<R<AuthOperate>> getById(@PathVariable Long id) {
        return R.ok(authOperateRepository.findById(id));
    }

    /**
     * 更新操作信息
     * @param id 要更新的操作ID
     * @param entity 包含更新信息的操作对象
     * @return 更新后的操作对象
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新操作", description = "更新指定ID的操作信息")
    public Mono<R<AuthOperate>> update(@PathVariable Long id, @RequestBody AuthOperate entity) {
        return authOperateRepository.findById(id)
                // 根据ID查找现有操作
                .flatMap(existingRole -> {
                    entity.setId(id);
                    entity.setUpdateTime(LocalDateTime.now());
                    // 更新操作信息
                    return R.ok(authOperateRepository.save(entity));
                    // 保存更新后的操作
                })
                .switchIfEmpty(R.failed("更新操作失败"));
        // 如果找不到操作，抛出404错误
    }

    /**
     * 删除操作
     * @param id 要删除的操作ID
     * @return 无返回值
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除操作", description = "删除指定ID的操作")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public Mono<R<Void>> delete(@PathVariable Long id) {
        return R.ok(authOperateRepository.deleteById(id));
        // 根据ID删除操作
    }

    /**
     * 获取所有操作
     * @return 所有操作的列表
     */
    @GetMapping
    @Operation(summary = "获取所有操作", description = "获取所有操作的列表")
    public Mono<R<List<AuthOperate>>> getAll() {
        return R.ok(authOperateRepository.findAll());
        // 获取所有操作
    }

    /**
     * 获取操作数量
     * @return 符合条件的操作数量
     */
    @GetMapping("/count")
    @Operation(summary = "获取操作数量", description = "获取符合条件的操作数量")
    public Mono<R<Long>> count() {
        return R.ok(authOperateRepository.count());
    }

    /**
     * 分页获取操作
     * @param page 页码
     * @param size 每页大小
     * @return 分页后的操作列表
     */
    @GetMapping("/page")
    @Operation(summary = "分页获取操作", description = "分页获取操作列表")
    public Mono<R<List<AuthOperate>>> getPage(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return R.ok(authOperateRepository.findAll()
                // 获取所有操作
                .skip((long) page * size)
                // 跳过前面的操作
                .take(size))
                ;
    }

    /**
     * 获取操作的角色
     * @param interfaceId 操作ID
     * @return 拥有指定操作的用户列表
     */
    @GetMapping("/roles")
    @Operation(summary = "获取操作对应的角色", description = "获取指定操作ID或操作标记的所有角色")
    public Mono<R<List<AuthRole>>> getRoles(
            @RequestParam(required = false) Long interfaceId) {
        if (interfaceId != null) {
            return R.ok(
                    authRolePowerRepository.findByInterfaceId(interfaceId)
                            // 根据操作ID查找用户操作关系
                            .flatMap(roleInterface -> authRoleRepository.findById(roleInterface.getRoleId()))
            );
            // 根据用户ID查找用户
        } else {
            return R.ok();
        }
    }
}
